package com.wx.mythread.background;


import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 第一种：运行结果错误
 * 计数不准确，找出具体错误的位置
 */
public class MultiThreadsError implements Runnable{

    static MultiThreadsError instance = new MultiThreadsError();

    //AtomicInteger原子整型（保证原子操作）
    static AtomicInteger realIndex = new AtomicInteger();
    static AtomicInteger wrongCount = new AtomicInteger();

    //设置栅栏
    static volatile CyclicBarrier cyclicBarrier1 = new CyclicBarrier(2);
    static volatile CyclicBarrier cyclicBarrier2 = new CyclicBarrier(2);


    //设置标记位
    static boolean[] marked = new boolean[100000];

    static int index = 0;

    @Override
    public void run() {
        // while (index < 10000){
        //     index++;
        // }
        for (int i = 0; i < 10000; i++) {
            try {
                //设置栅栏，必须两个线程同时到达这里，才可以往下继续运行
                cyclicBarrier1.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            index++;
            realIndex.incrementAndGet();
            try {
                cyclicBarrier2.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            synchronized (instance) {
                if (marked[index] && marked[index-1]) {
                    System.out.println("发生了错误:" + index);
                    wrongCount.incrementAndGet();
                }
                marked[index] = true;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        marked[0] = true;
        Thread thread1 = new Thread(instance);
        Thread thread2 = new Thread(instance);
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println("index表面结果="+ index);
        System.out.println("realIndex真正运行次数="+realIndex);
        System.out.println("wrongCount真正错误次数="+wrongCount);
    }
}
